home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / faq / fds-310.lha / FindDesc11.lha / FindDesc.c < prev    next >
C/C++ Source or Header  |  1995-09-27  |  7KB  |  201 lines

  1. /*
  2. **          FindDesc.c 1.1    Public domain, written by Marcus Ohlström
  3. **
  4. **      May be freely redistributed. You may use whatever part you want to
  5. **      in your own programs.
  6. **
  7. **      This program is written using 100% ANSI-C. That means you can
  8. **      compile it with any c-compiler supporting the ANSI-standard, which
  9. **      most c-compilers do.
  10. **
  11. **      In case of problems, or if you have any questions, e-mail me at
  12. **      marcus@karkis.canit.se and I will try to help you!
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <ctype.h>
  19.  
  20. #define START_STR     "@BEGIN USG_FILEDESC"
  21. #define END_STR       "@END USG_FILEDESC"
  22. #define SHORT_END_STR "END:"
  23.  
  24. #define MAX_LEN 22        /* may NOT be smaller than strlen(START_STR) */
  25.  
  26. #define FALSE 0
  27. #define TRUE  1
  28.  
  29. int main(int, char **);
  30. int finddesc(FILE *, long int *, long int *);
  31. void fprintfdesc(FILE *, FILE *, long int, long int);
  32.  
  33. int main(int argc, char **argv)
  34. {
  35.     FILE *in = NULL, *out = stdout;
  36.     long int start, end;
  37.     int exitcode = 20;
  38.     
  39.     if(argc == 2 || argc == 3)
  40.     {
  41.         if(NULL != (in  = fopen(argv[1], "r")))
  42.         {
  43.             if(NULL != finddesc(in, &start, &end))
  44.             {
  45.                 /*  do not open out until we are sure an USG-desc exists  */
  46.                 if((3 == argc) && (NULL == (out = fopen(argv[2], "w"))))
  47.                 {
  48.                     fprintf(stderr, "Could not create \"%s\", using stdout instead.\n\n", argv[2]);
  49.                     out = stdout;
  50.                 }
  51.                 fprintfdesc(in, out, start, end);
  52.                 exitcode = 0; /*  everything worked fine  */
  53.             } else fprintf(stderr, "Could not find filedescription.\n");
  54.         } else fprintf(stderr, "Could not open \"%s\".\n", argv[1]);
  55.     } else fprintf(stderr, "Usage: %s infile [outfile]\n", argv[0]);
  56.     
  57.     if(in  != NULL)     fclose(in);
  58.     if(out != stdout)   fclose(out);
  59.     
  60.     return(exitcode);
  61. }
  62.  
  63. /*
  64.  *   finddesc() requires 3 arguments:
  65.  *
  66.  *   FILE *in            should be a pointer to the file to read from
  67.  *   long int *startptr  will be set to point at the beginning of the description
  68.  *   long int *endptr    will be set to point at the end of the description
  69.  *
  70.  *   finddesc() will return 0 if it fails and 1 if it succeeds
  71.  */
  72. int finddesc(FILE *in, long int *startptr, long int *endptr)
  73. {
  74.     char *buffer, *pos = NULL, *tmp;
  75.     size_t size;
  76.     int success = FALSE;
  77.     int cnt;
  78.     
  79.     if(NULL != (buffer = malloc(MAX_LEN + 1)))
  80.     {
  81.         buffer[MAX_LEN] = '\0';
  82.         
  83.         /*  while (we haven't found "@BEGIN FILEDESC") and (we do get some text)  */
  84.         while((NULL == pos) && (NULL != (size = fread(buffer, 1, MAX_LEN, in))))
  85.         {
  86.             /*  search through the whole buffer  */
  87.             for(cnt = 0; cnt <= MAX_LEN; cnt += strlen(&buffer[cnt]) + 1)
  88.             {
  89.                 /*  did we found a match?  */
  90.                 if(NULL != (pos = strstr(&buffer[cnt], START_STR)))
  91.                     break;
  92.             }
  93.             
  94.             if(NULL == pos)
  95.             {
  96.                 /*  we haven't found any match, now check the last chars  */
  97.                 if(NULL != (tmp = strchr(&buffer[MAX_LEN+2-sizeof(START_STR)], '@')))
  98.                 {
  99.                     if(NULL == strncmp(tmp, START_STR, strlen(tmp)))
  100.                         /*  found something that can be a match! Rewind  */
  101.                         /*  the FILE-pointer and read it again           */
  102.                         fseek(in, (long) 0-strlen(tmp), SEEK_CUR);
  103.                 }
  104.             }
  105.         }
  106.         
  107.         pos += strlen(START_STR);
  108.         while(isspace(*pos))        /*  skip all whitespaces  */
  109.             pos++;
  110.         
  111.         fseek(in, 0-size+(pos-buffer), SEEK_CUR);
  112.         
  113.         if(!feof(in))
  114.         {
  115.             *startptr = ftell(in);
  116.             
  117.             pos = NULL;
  118.             
  119.             /*  while (we haven't found "@END FILEDESC") and (we do get some text)  */
  120.             while((NULL == pos) && (NULL != (size = fread(buffer, 1, MAX_LEN, in))))
  121.             {
  122.                 /*  search through the whole buffer  */
  123.                 for(cnt = 0; cnt <= MAX_LEN; cnt += strlen(&buffer[cnt]) + 1)
  124.                 {
  125.                     /*  did we found a match?  */
  126.                     if(NULL != (pos = strstr(&buffer[cnt], END_STR)))
  127.                         break;
  128.                 }
  129.                 
  130.                 if(NULL == pos)
  131.                 {
  132.                     /*  we haven't found any match, now check the last chars  */
  133.                     if(NULL != (tmp = strchr(&buffer[MAX_LEN+2-sizeof(END_STR)], '@')))
  134.                     {
  135.                         if(NULL == strncmp(tmp, END_STR, strlen(tmp)))
  136.                             /*  found something that can be a match! Rewind  */
  137.                             /*  the FILE-pointer and read it again           */
  138.                             fseek(in, (long) 0-strlen(tmp), SEEK_CUR);
  139.                     }
  140.                 }
  141.             }
  142.             
  143.             fseek(in, 0-size+(pos-buffer), SEEK_CUR);
  144.             
  145.             if(!feof(in))
  146.             {
  147.                 *endptr = ftell(in);
  148.                 success = TRUE;
  149.             } else {
  150.                 /*  did not find "@END FILEDESC", search for "%END:" or "$END:"  */
  151.                 fseek(in, *startptr, SEEK_SET);
  152.                 
  153.                 /*  while we get some text  */
  154.                 while(NULL != fgets(buffer, MAX_LEN, in))
  155.                 {
  156.                     /*  did we find "%END:" or "$END:" or did we not?  */
  157.                     if(NULL == strncmp(&buffer[1], SHORT_END_STR, 4) && (buffer[0] == '%' || buffer[0] == '$'))
  158.                         break;
  159.                 }
  160.                 
  161.                 if(!feof(in))
  162.                 {
  163.                     /*  set endposition, do not print anything after "?END:"  */
  164.                     fseek(in, (long) 5-strlen(buffer), SEEK_CUR);
  165.                     *endptr = ftell(in);
  166.                     success = TRUE;
  167.                 }
  168.             }
  169.         }
  170.         free(buffer);
  171.     }
  172.     
  173.     return(success);
  174. }
  175.  
  176. /*
  177.  *   fprintfdesc() requires 4 arguments:
  178.  *
  179.  *   FILE *in        a pointer to the file to read from
  180.  *   FILE *out       a pointer to the file to write to, or stdout
  181.  *   long int start  the startposition of the description, use with fseek()
  182.  *   long int end    the endposition of the description, use with fseek()
  183.  *
  184.  *   fprintfdesc() does not return any value
  185.  */
  186. void fprintfdesc(FILE *in, FILE *out, long int start, long int end)
  187. {
  188.     char *buffer;
  189.     size_t len = end-start;
  190.     
  191.     if(buffer=malloc(len))
  192.     {
  193.         if(fseek(in, start, SEEK_SET) || NULL == (fread(buffer, 1, len, in)) || len > fwrite(buffer, 1, len, out))
  194.             fprintf(stderr, "An error has occurred, terminating.\n");
  195.         else
  196.             if(buffer[len-1] != '\n')
  197.                 fputc('\n', out);
  198.         
  199.         free(buffer);
  200.     }
  201. }